Web服务就是让你的web应用提供一套web API,通常用SOAP
或
REST来实现。
.
REST就本身而言不是一种技术,而是一种架构模式。is not really a technology in itself, but more an architectural
pattern. REST非常简单,以普通XML或JSON作为通信机制,结合可以表现底层系统状态的URL形式和 HTTP方法如
GET, PUT, POST和 DELETE.
每一个HTTP方法映射到一个action,如用GET方法获取数据,用PUT方法创建数据,用POST更新数据等等。在这个意义上
REST非常适合 CRUD.
URL形式
要用Grails实现REST,第一步就是提供REST形式的URL映射
URL映射:
static mappings = {
"/product/$id?"(resource:"product")
}
这就将URI /product
映射到 ProductController
. 在controller内部每个HTTP方法,GET,PUT,POST和DELETE都映射到一个action上,如下表所示:
方法 |
Action |
GET |
show |
PUT |
update |
POST |
save |
DELETE |
delete |
可以通过URL映射机制修改HTTP方法和URL的映射关系:
"/product/$id"(controller:"product"){
action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]
}
但是在这个例子中,Grails并不像前面使用过的resource
参数那样自动提供XML或JSON序列化,除非提供在URL映射中提供parseRequest
参数:
"/product/$id"(controller:"product", parseRequest:true){
action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]
}
XML序列化 - 读取
controller可通过Grails提供的 XML序列化机制 来实现GET方法:
import grails.converters.*
class ProductController {
def show = {
if(params.id && Product.exists(params.id)) {
def p = Product.findByName(params.id)
render p as XML
}
else {
def all = Product.list()
render all as XML
}
}
..
}
这里,如果参数中指定id,通过id
搜索Product
如果指定id的Product存在,则返回该Product,否则返回所有Product. 这样,如果访问 /products
我们会得到所有的Product,如果访问/product/MacBook
,我们只获取到一个MacBook记录.
XML序列化 - 更新
为支持PUT
和 POST
你可以使用 params 对象。Grails中params对象具有读取XML数据包的能力。如下面的XML数据包:
<?xml version="1.0" encoding="ISO-8859-1"?>
<product>
<name>MacBook</name>
<vendor id="12">
<name>Apple</name>
</vender>
</product>
你可以通过在 数据绑定章节描述过的同样的方法,通过 params 对象来读取XML数据:
def save = {
def p = new Product(params['product']) if(p.save()) {
render p as XML
}
else {
render p.errors
}
}
在这个例子中,通过提取 params
对象中的 'product'
对应的值,我们可以通过Product
的构建器自动创建和绑定XML数据 。 注意这一行:
def p = new Product(params['product'])
这里我们不需要修改任何代码就可以以处理XML数据请求的方法处理表单提交。同样的方法也可以用来处理JSON请求.
如果需要对不同的客户端(REST,HTML等)提供不同的响应,你可以使用 content
negotation
The Product
object is then saved and
rendered as XML, otherwise an error message is produced using Grails' validation
capabilities in the form:
<error>
<message>The property 'title' of class 'Person' must be specified</message>
</error>
Grails通过
XFire
插件来支持SOAP。XFire插件使用流行的XFire SOAP协议栈,它允许你通过特定的expose
属性将Grails的
services
作为SOAP服务提供:
class BookService { static expose=['xfire']
Book[] getBooks(){
Book.list() as Book[]
}
}
WSDL文件可通过: http://127.0.0.1:8080/your_grails_app/services/book?wsdl
获取
更多信息参考XFire插件的wiki 文档 。
Grails没有直接提供对RSS和Atom的支持. You could
construct RSS or ATOM feeds with the
render
method's XML capability. 可以通过Grails
Feeds插件来构建RSS和Atom。改插件使用流行的
ROME
库. 下面是简单使用这个插件的例子:
def feed = {
render(feedType:"rss", feedVersion:"2.0") {
title = "My test feed"
link = "http://your.test.server/yourController/feed"
Article.list().each() {
entry(it.title) {
link = "http://your.test.server/article/${it.id}"
it.content // return the content
}
}
}
}